import re
import wsgiref.handlers
import SecretKey
from google.appengine.ext import webapp
from google.appengine.api import users

class keyAdminPage(webapp.RequestHandler):
  def __cmdHandler(self):
    """
    Receive the cmd parameter and decide what to do.
    cmd has three values: create, regenerate, delete 
    """
    
    cmd = self.request.get('cmd')
    if cmd == 'create':
      tk = self.request.get('tk_name')
      try:
        # Validation of tk parameter
        if re.search("[^0-9a-zA-Z]",tk):
          raise ValueError
        SecretKey.createKey(tk)
        self.redirect('/keyAdmin')
      except ValueError:
        self.response.out.write("""
    <div style="color: red">ERROR: <b>tk</b> parameter is wrong. Only letters and digits are acceptable.</div>""")
      except SecretKey.DuplicateKeyException:
        self.response.out.write("""
    <div style="color: red">ERROR: This tk already existed.</div>""")
    elif cmd == 'regenerate' or cmd == 'delete':
      func = { 'regenerate': SecretKey.regenerateKey,
               'delete':     SecretKey.deleteKey }
      ids = self.request.get('ids', allow_multiple=True)
      for i in ids:
        try:
          func[cmd](i)
          self.redirect('keyAdmin')
        except SecretKey.KeyNotFoundException:
          self.response.out.write("""
    <div style="color: red">ERROR: Cannot find this key</div>""")

  def __displayHead(self):
    self.response.out.write("""
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Key Admin Page</title>
    <script type="text/javascript"">
    function setCommand(cmd)
    {
        document.getElementById("cmd").value=cmd;
    }
    </script>
</head>
<body>""")

  def __displayForm(self):
    self.response.out.write("""
    <form id="admin_form" action="keyAdmin" method="get">
    <fieldset><legend>Create new Secret Key</legend>
        <input type="hidden" id="cmd" name="cmd" value="create" />
        If you want to create a secret key for a new tk name, please enter the tk name. <br />
        New tk name: <input type="text" name="tk_name" style="width: 600px" />
        <input type="submit" value="Create" onclick="setCommand('create')" />
    </fieldset><br />
    <table style="background-color: silver">
        <tr><th>selected</th><th>tk name</th><th>secret key</th></tr>""")
    keys = SecretKey.getAllKey()
    if keys.count(1) == 0:
      self.response.out.write("""
        <tr style="background-color: white"><td colspan="3">No Key Found</td></tr>""")
    else:
      for a_key in keys:
        self.response.out.write("""
        <tr style="background-color: white">
            <td><input type="checkbox" name="ids" value="%s" /></td>
            <td><div style="width: 600px; height: 2.2em; overflow: auto;">%s</div></td>
            <td>%s</td>
        </tr>""" % ( a_key.key(), a_key.tk_name, a_key.uuid ))
    self.response.out.write("""
    </table>
    <input type="submit" value="Regenerate" onclick="setCommand('regenerate')" /> 
    <input type="submit" value="Delete" onclick="setCommand('delete')" />
    </form>""")

  def __displayTail(self):
    self.response.out.write("""
</body>
</html>""")

  def __displayHMAC(self):
    # Calculate the HMAC (usually the HMAC is calculated by a real client, but we generate it in here 
    # for manual tests
    tk = "z01q6amlqnmqt53r6v1m9qqpidhc209tiiesoocubjpu6kasvhcupkjiae5n8mge3mtkc5uqeu4ja28ja18r396rrsqnoqd2kfse76vbikao3od27u9blifmqv2fq07sfvaaohmevuosfi71gtk32sirpjrarouhtuaabe2l1"
    hmacTmp = SecretKey.getHMAC(tk)
    self.response.out.write("""
<p><b>For testing purpose only.</b><br/>The HMAC (for the static TK key) is: <b>%s</b>
<br>Note: Keep it safe (to make it harder to generate collision attacks); it is generated in here only for testing purpose.</p>
""" % (hmacTmp))

  def get(self):
    self.__displayHead()
    user = users.get_current_user()
    if not user:
      self.redirect(users.create_login_url("/keyAdmin"))
      return ;
    elif not users.is_current_user_admin():
      self.response.out.write("""
You are not authorized to view this page.<br />
Please login as a administrator.<br />
<a href="%s">logout</a>
""" % users.create_logout_url("/keyAdmin"))
    else:
      self.__cmdHandler()
      self.__displayForm()
    self.__displayHMAC()
    self.__displayTail()

def main():
  mapping=[('/keyAdmin',keyAdminPage)]
  application = webapp.WSGIApplication(mapping)
  wsgiref.handlers.CGIHandler().run(application)

if __name__ == "__main__":
  main()
